package com.itany.shop.dao.impl;

import com.itany.shop.dao.OrderDao;
import com.itany.shop.entity.Item;
import com.itany.shop.entity.Order;
import com.itany.shop.entity.Product;
import com.itany.shop.entity.User;
import com.itany.shop.exception.DataAccessException;
import com.itany.shop.factory.ObjectFactory;
import com.itany.shop.rowmapper.OrderRowMapper;
import com.itany.shop.util.JDBCTemplate;
import com.itany.shop.util.JDBCUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * Author:shixiaojun@itany.com
 * Date:2022/4/19 10:16
 * Version:1.0-SNAPSHOT
 * Description:
 */
public class OrderDaoImpl implements OrderDao {

    private JDBCTemplate jdbcTemplate = (JDBCTemplate) ObjectFactory.getObject("jdbc");

    @Override
    public Integer insertReturnPrimaryKey(Order order) throws DataAccessException {
        String sql = new StringBuffer()
                .append(" insert into ")
                .append(" t_order ")
                .append("   (no,price,user_id)")
                .append(" values ")
                .append("   (?,?,?)")
                .toString();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        Integer orderId = null;
        try {
            conn = JDBCUtil.getConnection();
            // 设置保存后返回主键
            ps = conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
            ps.setString(1,order.getNo());
            ps.setDouble(2,order.getPrice());
            ps.setInt(3,order.getUser().getId());
            // 执行保存操作
            ps.executeUpdate();

            // 当执行完成保存操作之后,主键将会生成
            // 此时可以获取生成的主键的值
            rs = ps.getGeneratedKeys();
            // 由于生成的主键的结果集的字段是由数据库自动定义的
            // 而开发人员可能无法确定字段名是什么
            // 但是,结果集中有且仅有一个字段
            // 因此,此处一般使用索引号进行映射
            if(rs.next()){
                orderId = rs.getInt(1);
            }
            return orderId;
        } catch (DataAccessException e) {
            throw e;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DataAccessException("数据访问异常");
        }

    }

    @Override
    public List<Order> selectByUserId(Integer userId) throws DataAccessException {
        String sql = new StringBuffer()
                .append(" select id,no,price,user_id")
                .append(" from t_order ")
                .append(" where user_id = ? ")
                .toString();
        List<Order> orders = jdbcTemplate.query(sql,new OrderRowMapper(),userId);
        return orders.isEmpty()?null:orders;
    }

    @Override
    public Order selectDetailById(Integer id) throws DataAccessException {
        String sql = new StringBuffer()
                .append(" select o.id,u.username,o.no,p.name,i.num,o.price,i.price 'item_price', ")
                .append(" (select count(1) from t_item where order_id = o.id) count ")
                .append(" from t_order o ")
                .append(" join t_item i ")
                .append("   on i.order_id = o.id ")
                .append(" join t_user u ")
                .append("   on o.user_id = u.id ")
                .append(" join t_product p ")
                .append("   on i.product_id = p.id ")
                .append(" where o.id = ? ")
                .toString();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        Order order = null;
        try {
            conn = JDBCUtil.getConnection();
            ps = conn.prepareStatement(sql);
            ps.setInt(1,id);
            rs = ps.executeQuery();
            while(rs.next()){

                // 一方数据映射
                // 一方数据在映射时只能映射一次
                // 如果出现多次,后面的会将前面的覆盖
                if(null == order) {
                    // 在没有映射之前,order为null
                    // 映射了之后,order不为null
                    order = new Order();
                    order.setId(rs.getInt("id"));
                    order.setPrice(rs.getDouble("price"));
                    order.setNo(rs.getString("no"));
                    order.setCount(rs.getInt("count"));
                    User user = new User();
                    user.setUsername(rs.getString("username"));
                    order.setUser(user);
                }
                // 多方数据映射
                // 多方数据在映射时映射多次
                // 每次映射后将映射的对象加入到一方数据的集合属性中
                Item item = new Item();
                Product product = new Product();
                product.setName(rs.getString("name"));
                item.setNum(rs.getInt("num"));
                item.setPrice(rs.getDouble("item_price"));
                item.setProduct(product);

                // 将多方数据加到一方数据的集合属性中
                order.addItem(item);
            }
            return order;
        } catch (DataAccessException e) {
            e.printStackTrace();
            throw e;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DataAccessException(e.getMessage());
        }
    }
}
